home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / comm / misc / DigiCam.lha / src / camera.c < prev    next >
C/C++ Source or Header  |  1999-07-15  |  9KB  |  402 lines

  1. /* camera.c (c) 1999 by Volker Remuß, remuss@cs.tu-berlin.de */
  2.  
  3. #include "machine_amiga.h"
  4. #include "camera.h"
  5. #include "cameraops.h"
  6.  
  7. #include <stdio.h>
  8.  
  9. static int32 serialspeed;
  10.  
  11. void closecamera(void)
  12. {
  13.     takeaction(FINISH_SESSION, 0);            // Send finish session to camera (sets camera back to 19200)
  14. }
  15.  
  16.  
  17. int initcamera(int32 initspeed, int32 communicationspeed, int16 quiet)
  18. {
  19.     unsigned char speed;
  20.     unsigned char ackbuf[1];
  21.     int16 i;
  22.  
  23.     serialspeed = communicationspeed;
  24.  
  25.     switch (communicationspeed)
  26.     {
  27.         case   9600: speed = 1; break;
  28.         case  19200: speed = 2; break;
  29.         case  38400: speed = 3; break;
  30.         case  57600: speed = 4; break;
  31.         case 115200: speed = 5; break;
  32.         case 230400: speed = 6; break;
  33.         case 460800: speed = 7; break;
  34.       default: printf("Serial speed unkown, using 19200 bps\n"); speed = 2; serialspeed = 19200; break;        // speed defaults to 19200 
  35.     }
  36.  
  37.     setlocalserialspeed(initspeed);
  38.  
  39.     buf[0] = 0x00;
  40.     writeserial(buf, 1);
  41.     delay(20);
  42.     ackbuf[0] = 0;
  43.     for (i=1; ackbuf[0] != 0x15; i++)
  44.     {
  45.             delay(5);
  46.             readserial(ackbuf, 1, 0);
  47.             if (!(i % 4))
  48.             {
  49.                 if (!(quiet)) printf("Calling Camera\n");
  50.                 writeserial(buf, 1);
  51.             }
  52.     }
  53.     
  54.     buf [0] =     0x1b;            // Commandpacket
  55.     buf [1] =     0x53;            // First in Session
  56.     buf [2] =     0x06;            // Datalength = 6
  57.     buf [3] =     0x00;            //     "
  58.     buf [4] =     0x00;            // 0 Command: set vlaue of int32 register
  59.     buf [5] =       17;            // Register 17: Set Communication Speed
  60.     buf [6] =    speed;            // data - set communication speed always < 0xff
  61.     buf [7] =     0x00;            // data
  62.     buf [8] =     0x00;            // data
  63.     buf [9] =     0x00;            // data
  64.     buf[10] = speed+17;         // checkSUM = data(speed) + Register(17) always < 0xff
  65.     buf[11] =     0x00; 
  66.  
  67.     writeserial(buf, 12);
  68.  
  69.     for (i=0; !readserial(buf, 1, 0); i++)
  70.     {
  71.         delay(5);
  72.         if (i > 50)
  73.         {
  74.             printf("Camera didn't answer properly ... timeout\n");
  75.             return(-1);
  76.         }
  77.     }
  78.  
  79.     if (buf[0] != 0x06)
  80.     {
  81.         printf("Speed NOT acknowledged by camera\n");
  82.         return (-1);
  83.     }
  84.     else
  85.         if (!(quiet)) printf("Speed acknowledged by camera\n");
  86.  
  87.     delay(5);
  88.     
  89.     setlocalserialspeed(communicationspeed);
  90.  
  91.     delay(25);
  92.  
  93.     return(0);
  94. }
  95.  
  96.  
  97. unsigned int16 checksum(unsigned char *srcbuf, int16 length)
  98. {
  99.     int16 i;
  100.     unsigned int16 sum=0;
  101.  
  102.     for (i=0; i<length; i++)
  103.         sum += srcbuf[i];
  104.  
  105.     return(sum);
  106. }
  107.  
  108.  
  109. int32 getint32reg(unsigned char reg)
  110. /*    Gets the contents of the an int32 register
  111.     and directly returns it contents.
  112.     Returns -1 in case of failure.
  113.  
  114.     Argument: Number of an int32-register
  115. */
  116. {
  117.     int16 size=0;
  118.     unsigned int16 checksum;
  119.  
  120.     checksum = (unsigned int16)reg + 0x01;
  121.  
  122.     buf[0] = 0x1b;
  123.     buf[1] = 0x43;
  124.     buf[2] = 0x02;
  125.     buf[3] = 0x00;
  126.     buf[4] = 0x01;
  127.     buf[5] = reg;
  128.     buf[6] = checksum & 0xff;
  129.     buf[7] = (checksum >> 8) & 0xff;
  130.  
  131.     writeserial(buf, 8);                                // send command
  132.  
  133.     getdatapacket(buf, &size, 0, 0);                // get packet, -size. Not interested in sequence.
  134.  
  135.     if (size != 4)
  136.     {
  137.         //printf("Int32-Register unreadable\n");
  138.         return (-1);
  139.     }
  140.  
  141.     return (buf[0] | buf[1] << 8 | buf[2] << 16 | buf[3] << 24);
  142. }
  143.  
  144.  
  145. int16 putint32reg(unsigned char reg, int32 data)
  146. {
  147.     unsigned int16 checksum;
  148.     unsigned char ackbuf[1];
  149.     int16 notacknowledged = 1;
  150.     unsigned char data0, data1, data2, data3;
  151.     int16 i;
  152.  
  153.     data0 = data & 0xff;
  154.     data1 = (data >>  8) & 0xff;
  155.     data2 = (data >> 16) & 0xff;
  156.     data3 = (data >> 24) & 0xff;
  157.  
  158.     checksum = (unsigned int16)data0 + data1 + data2 + data3 + reg;
  159.  
  160.     buf[0]  = 0x1b;
  161.     buf[1]  = 0x43;
  162.     buf[2]  = 0x06;
  163.     buf[3]  = 0x00;
  164.     buf[4]  = 0x00;
  165.     buf[5]  = reg;
  166.     buf[6]  = data0;
  167.     buf[7]  = data1;
  168.     buf[8]  = data2;
  169.     buf[9]  = data3;
  170.     buf[10] = checksum & 0xff;
  171.     buf[11] = (checksum >> 8) & 0xff;
  172.  
  173.     while (notacknowledged)
  174.     {
  175.         writeserial(buf, 12);
  176.         for (i=0; !readserial(ackbuf, 1, 0); i++)
  177.         {
  178.             delay(5);
  179.             if (i > 50)
  180.             {
  181.                 printf("Timeout in putint32\n");
  182.                 ackbuf[0] = 0;
  183.                 break;
  184.             }
  185.         }
  186.  
  187.         if (ackbuf[0] != 0x06)
  188.         {
  189.             if (ackbuf[0] == 0x11)
  190.             {
  191.                 printf("Operation denied by camera\n", reg);
  192.                 return(-1);
  193.             }
  194.             notacknowledged = 1;
  195.             
  196.         }
  197.         else
  198.             notacknowledged = 0;
  199.     }
  200.  
  201.     return(0);
  202. }
  203.  
  204.  
  205. int16 initgetvdatareg(unsigned char reg)
  206. /*
  207.     This function sends the command to read a vdata-register. The caller has
  208.     to receive the incoming datapackets at his own by calling getdatapacket
  209.     for every single packet for a whole sequence of packets.
  210.     Interrupting a sequence of datapackets is not supported.
  211.  
  212.     Always returns 0 since there is no other acknowledgment than incoming
  213.     datapackets.
  214.  
  215.     Argument: Number of a vdata-register
  216. */ 
  217. {
  218.     unsigned int16 checksum;
  219.  
  220.     checksum = (unsigned int16)reg + 0x04;
  221.  
  222.     buf[0] = 0x1b;                            // Command
  223.     buf[1] = 0x43;                            // not the first in session
  224.     buf[2] = 0x02;                            // length = 2;
  225.     buf[3] = 0x00;                            //    ""
  226.     buf[4] = 0x04;                            // Command: Read vdata
  227.     buf[5] = reg;                            // which register
  228.     buf[6] = checksum & 0xff;    
  229.     buf[7] = (checksum >> 8) & 0xff;
  230.  
  231.     writeserial(buf, 8);                        // send command
  232.                                                     // command is not acknowledge.
  233.                                                     // camera responds with data packages
  234.  
  235.     return (0);                                    // no errorcodes here (yet ?)
  236.  
  237. }
  238.  
  239.  
  240. int16 getdatapacket(unsigned char *destbuf, int16 *datasize, int16 *waslastpacket, int16 *sequencenumber)
  241. /* 
  242.    getdatapacket retrieve an Datapacket of unknown size.
  243.     The given buffer has to be big enough to keep the whole packet.
  244.     Size of the packet's dataarea is always returned in datasize
  245.     waslastpaket and sequencenumber only returned if pointer != 0
  246.  
  247.     Only data of packet is returned.
  248. */
  249. {
  250.     unsigned char ackbuf[1];
  251.     int16 i;
  252.     int16 res;
  253.     int16 notacknowledged = 1;                // needed to enable rereceiving of damaged packets
  254.     int16 error;
  255.  
  256.     while(notacknowledged)                    // loop to re-receive damaged packets
  257.     {
  258.         for (i = 0; inreadbuffer() < 4; i++)        // timeout loop for datapackets needed e.g. when
  259.         {                                                        // trying to read write-only registers
  260.             delay(1);
  261.             if (i > 10)                                        // wait for packetheader (4 byte) or error (1 byte) code
  262.             {
  263.                 if ((res=inreadbuffer()) > 0 && (res < 3))    // maybe camera reports illegal command?
  264.                 {                                                        // that would be a single 0x11, but since
  265.                     readserial(ackbuf, 1, 1);                    // there was some delay camera maybe closed
  266.                     if (ackbuf[0] == 0x11)                        // session already (0xff). Therefore < 3
  267.                     {
  268.                         printf("Operation denied by camera ");
  269.                         *datasize = 0;
  270.                         return(-1);
  271.                     }
  272.                 }
  273.                 printf("Datapaket timed out.\n");
  274.                 *datasize = 0;
  275.                 return (-1);
  276.             }
  277.         }
  278.  
  279.         if (4 != readserial(destbuf, BUFSIZE, 4)) printf("Error while reading datapacket!");
  280.  
  281.         if (waslastpacket)
  282.             switch (destbuf[0])
  283.             {
  284.                 case 0x02: *waslastpacket = 0; break;  // datapacket
  285.                 case 0x03: *waslastpacket = 1; break;  // lastdatapacket
  286.                     default: break; //return (-1);                       // NO datapacket
  287.             }
  288.  
  289.         if (sequencenumber) *sequencenumber = (int16) destbuf[1];
  290.  
  291.         *datasize = destbuf[2] | (destbuf[3] << 8);
  292.  
  293.  
  294.         for (i=0, error = 0; inreadbuffer() != *datasize+2; i++)
  295.         {
  296.             delay(5);
  297.             if (i>(2100+1050)/(serialspeed/100))
  298.             {
  299.                 //printf("timeout data ");
  300.                 readserial(destbuf, BUFSIZE, 0);
  301.                 error = 1;
  302.                 break;
  303.             }
  304.         }        
  305.  
  306.         if (!error)
  307.             if (*datasize+2 != readserial(destbuf, BUFSIZE, *datasize+2)) 
  308.             {
  309.                 printf("Error while reading datapacket!\n");
  310.                 error=1;
  311.             }
  312.  
  313.         if (!error && (checksum(destbuf, *datasize) == (destbuf[*datasize] | (destbuf[*datasize+1] << 8))))
  314.         {
  315.             ackbuf[0] = 0x06;
  316.             notacknowledged = 0;
  317.         }
  318.         else
  319.         {
  320.             printf("!");
  321.             fflush(stdout);
  322.             ackbuf[0] = 0x15;
  323.         }
  324.     
  325.         writeserial(ackbuf, 1);
  326.     }
  327. }
  328.  
  329.  
  330. int16 takeaction(unsigned char action, unsigned char argument)
  331. {
  332.     unsigned int16 checksum;
  333.     unsigned char ackbuf[2];
  334.     int16 notacknowledged = 1;
  335.     int16 i;
  336.  
  337.     checksum = (unsigned int16)action + argument + 0x02;
  338.  
  339.     buf[0] = 0x1b;
  340.     buf[1] = 0x43;
  341.     buf[2] = 0x03;
  342.     buf[3] = 0x00;
  343.     buf[4] = 0x02;
  344.     buf[5] = action;
  345.     buf[6] = argument;
  346.     buf[7] = checksum & 0xff;
  347.     buf[8] = (checksum >> 8) & 0xff;
  348.  
  349.    if (action == FINISH_SESSION)
  350.     {
  351.         writeserial(buf, 9);                            // send command
  352.         return(0);                                         // FINISH_SESSION is not acknowledged
  353.     }
  354.  
  355.     while (notacknowledged)
  356.     {
  357.         writeserial(buf, 9);                                // send command
  358.         
  359.         for (i=0; inreadbuffer() == 0; i++)
  360.         {
  361.             delay(5);
  362.             if (i > 100)
  363.             {
  364.                 printf("Timeout Takeaction 1\n");
  365.                 return(-1);
  366.             }
  367.         }
  368.         readserial(ackbuf, 1, 1);
  369.              
  370.         if (ackbuf[0] == 0x06)
  371.         {
  372.             //readserial(ackbuf, 1, 1);
  373.             for (i=0; !readserial(ackbuf, 1, 0); i++)
  374.             {
  375.                 delay(5);
  376.                 if (i > 50)
  377.                 {
  378.                     printf("Timeout Takeaction 2\n");
  379.                     ackbuf[0] = 0;
  380.                     break;
  381.                 }
  382.             }
  383.  
  384.             if (ackbuf[0] == 0x05)
  385.                 notacknowledged = 0;
  386.             else
  387.                 notacknowledged = 1;
  388.         }
  389.         else
  390.         {
  391.             if (ackbuf[0] == 0x11)
  392.             {
  393.                 printf("Action %d denied by camera\n", (int16)action);
  394.                 return(-1);
  395.             }
  396.             notacknowledged = 1;
  397.         }
  398.     }        
  399.  
  400.     return(0);
  401. }
  402.